-- If you're not sure your plugin is executing, uncomment the line below and restart Kong
-- then it will throw an error which indicates the plugin is being loaded at least.

--assert(ngx.get_phase() == "timer", "The world is coming to an end!")

---------------------------------------------------------------------------------------------
-- In the code below, just remove the opening brackets; `[[` to enable a specific handler
--
-- The handlers are based on the OpenResty handlers, see the OpenResty docs for details
-- on when exactly they are invoked and what limitations each handler has.
---------------------------------------------------------------------------------------------
local http = require("resty.http")
local cjson = require("cjson.safe").new()
local string_find = string.find
local ck  = require("resty.cookie")
local kong = kong
local SESSION_ID = "sessionId"

local plugin = {
  PRIORITY = 1007, -- set the plugin priority, which determines plugin execution order
  VERSION = "0.1",
}

function plugin:init_worker()

  kong.log.debug("saying hi from the 'init_worker' handler")

end



function plugin:certificate(plugin_conf)

  kong.log.debug("saying hi from the 'certificate' handler")

end


function plugin:rewrite(plugin_conf)

  kong.log.debug("saying hi from the 'rewrite' handler")

end

local function dolphin(conf, userName, userPassword)
  kong.log.debug("**********")
  local login_api = conf.login_api
  local httpc = http.new()
  local ssobody = 'userName=' .. userName .. '&userPassword=' .. userPassword
  kong.log.debug(login_api)
  kong.log.debug(ssobody)

  local res, err = httpc:request_uri(
    login_api,
    {
      ssl_verify = ssl_verify or false,
      headers = { ["Content-Type"] = "application/x-www-form-urlencoded"},
      method = "POST",
      body = ssobody,
    }
  )
  kong.log.debug(res.status)
  kong.log.debug("**********")
  if not res or err or 200 ~= res.status then
    return kong.response.exit(401, { message = "login dss failed!" })
  end

  local ret_info = cjson.decode(res.body)
  kong.log.inspect(ret_info)
  if not ret_info.msg or ret_info.msg ~= "login success" then
    return kong.response.exit(401, { message = "login dss failed!" })
  end
  return ret_info
end


local function request_token(conf, userName, userPassword, sessionId)
  local lua_object = {
    ["client_id"] = conf.client_id,
    ["client_secret"] = conf.client_secret,
    ["grant_type"] = "password",
    ["scope"] = "email",
    ["provision_key"] = conf.provision_key,
    ["authenticated_userid"] = userName,
    ["username"] = userName,
    ["password"] = userPassword,
    ["redirect_uri"] = conf.redirect_uri
  }

  kong.log.inspect(lua_object)
  local oauth2body = cjson.encode(lua_object)
  kong.log.debug(oauth2body)
  local httpc = http.new()
  local resp, err_token = httpc:request_uri(
    conf.token_api,
    {
      ssl_verify = ssl_verify or false,
      headers = { ["Content-Type"] = "application/json;"},
      method = "POST",
      body = oauth2body,
    }
  )
  if not resp or err_token or 200 ~= resp.status then
    return kong.response.exit(401, { message = "load token failed!" })
  end

  local token_info = cjson.decode(resp.body)
  token_info['session_id'] = sessionId
  kong.log.inspect(token_info)
  return token_info
end


local function del_token(access_token, sessionId)
  local token = kong.db.oauth2_tokens:select_by_access_token(access_token)
  if token then
    kong.log.debug(kong.router.get_service().id)
    kong.log.inspect(token)
    if (token.service and token.service.id and
      kong.router.get_service().id ~= token.service.id) then
      return kong.response.exit(401, { message = "invalid token!" })
    end
    if sessionId and token.authenticated_userid ~= sessionId then
      return kong.response.exit(401, { message = "invalid sessionId!" })
    end
    kong.db.oauth2_tokens:delete({ id = token.id })
    local token_cache_key = kong.db.oauth2_tokens:cache_key(access_token)
    kong.cache:invalidate(token_cache_key)
    return
  end
  return kong.response.exit(401, { message = "invalid sessionId!" })
end


function plugin:access(conf)

  kong.log.inspect(conf)

  if kong.request.get_method() == "POST" then
    local path = kong.request.get_path()


    kong.log.debug("*********************")
    kong.log.debug(path)
    kong.log.debug("*********************")

    local from = string_find(path, "/dss/login", nil, false)
    if from then
      local body_args = kong.request.get_body()
      if not body_args then
        return kong.response.exit(500, { message = "params is missing" })
      end
      kong.log.inspect(body_args)
      local userName = body_args["userName"]
      local userPassword = body_args["userPassword"]
      local dol_res = dolphin(conf, userName, userPassword)
      local token_res = request_token(conf, userName, userPassword, dol_res.data.sessionId)

      if not ctx then
        ctx = ngx.ctx
      end

      local mycookie = {
        key = SESSION_ID,
        value = dol_res.data.sessionId,
        path = "/"
      }

      local cookie = ck:new()
      local ok, err = cookie:set(mycookie)

      if not ok then
        kong.log.debug("cookies failed")
      end

      return kong.response.exit(200, token_res, {
        [SESSION_ID] = dol_res.data.sessionId
      })
    end

    from = string_find(path, "/dss/logout", nil, false)
    if from then
      local sessionId = ngx.var.cookie_sessionId
      kong.log.debug("******************")
      kong.log.debug(sessionId)
      kong.log.debug("******************")

      local access_token = kong.request.get_header(conf.request_header)
      if not access_token then
        return kong.response.exit(401, { message = "access_token must be put in headers" })
      end
      del_token(access_token, sessionId)
      return kong.response.exit(200, { message = "logout success~" })
    end
  end

  return
end

--[[
function plugin:header_filter(conf)
  local row, err = kong.db.myplugin:select_by_key("")
  ngx.header[conf.response_header] = "this is on the response"

end


function plugin:body_filter(conf)

  -- your custom code here
  kong.log.debug("saying hi from the 'body_filter' handler")

end
]]

--[[ runs in the 'log_by_lua_block'
function plugin:log(plugin_conf)

  -- your custom code here
  kong.log.debug("saying hi from the 'log' handler")

end --]]


-- return our plugin object
return plugin
